<?php
/**
 * Created by 99468
 * Date: 2017/9/10
 * Time: 14:14
 * Author: weblinuxgame
 * email : 994685563@qq.com
 * license : MTI
 **/
namespace EpgApp\modules\sdks\Image\base\gbclass;

function_exists('gd_info') or die('gd module not exist!');
defined('DS') or define('DS',DIRECTORY_SEPARATOR);

use EpgApp\modules\sdks\Image\base\ImageException ;

class ImageSDK
{
    const GIF = IMG_GIF ;
    const JPG = IMG_JPEG ;
    const XPM = IMG_XPM;
    const PNG = IMG_PNG ;
    const WBMP = IMG_WBMP ;
    const BMP  = 0xFF ;

    protected static $SupportTypeCode = array(
        'gif'=>self::GIF,'jpg'=>self::JPG,
        'xpm'=>self::XPM,'png'=>self::PNG,
        'wbmp'=>self::WBMP,'bmp'=>self::BMP,
    );

    protected static $TypeMap = array(
        '','GIF','JPG', 'PNG','SWF',
        'PSD','BMP','TIFF(intel byte order)',
        'TIFF(motorola byte order)','JPC',
        'JP2','JPX','JB2','SWC','IFF','WBMP',
        'XBM',
    );

    private static $cache = array();

    public function __construct($filename)
    {
        $resource = new ImageResource($filename);
        if(empty($resource))
        {
            $error = 'class init failed';
            $code  = ImageException::_code($error);
            throw  new ImageException(ImageException::createMsgByCode($code,__CLASS__),$code);
        }
       // var_dump($resource);
        self::$cache['resource'] = $resource::getResource() ;
        self::$cache['filename'] = $filename ;
        self::$cache['self'] = $this;
    }

    /**
     * @param $imageFileOrTypeStr
     * @return bool|int|string
     */
    public static function getImageTypeCode($imageFileOrTypeStr='')
    {
        if(empty($imageFileOrTypeStr))
        {
            if($imageFileOrCode = self::getCache('type'))
            {
                foreach ($imageFileOrCode as $key=>$value)
                {
                    return $value;
                }
            }
            if(self::getCache('resource'))
            {
                $ret = self::getImageInfo();
                if(!empty($ret) && isset($ret['type']))
                {
                    return $ret['type'];
                }
            }
            return false ;
        }
        if(is_string($imageFileOrTypeStr))
        {
            if(is_file($imageFileOrTypeStr))
            {
               $type  = static::getImageInfo($imageFileOrTypeStr,'type');
               if(!empty($type)&&is_numeric($type))
               {
                   return $type;
               }
            }

            foreach (self::$TypeMap as $key=>$value)
            {
                if($value == $imageFileOrTypeStr)
                {
                    return $key ;
                }
            }

        }
        return false ;
    }

    /**
     * @param $imageFileOrCode
     * @return mixed|string
     */
    public static function getImageTypeStr($imageFileOrCode='')
    {
        if(empty($imageFileOrCode))
        {
            if($imageFileOrCode = self::getCache('type'))
            {
                foreach ($imageFileOrCode as $key=>$value)
                {
                    return $key;
                }
            }
            if(self::getCache('resource'))
            {
                $ret = self::getImageInfo();
                if(!empty($ret) && isset($ret['type']))
                {
                        return self::getImageTypeStr($ret['type']);
                }
            }
            return '';
        }
        if(is_file($imageFileOrCode))
        {
           $type = self::getImageTypeCode($imageFileOrCode);
           if(!empty($type)&&is_numeric($type)&&$type>0&&$type<count(self::$TypeMap))
           {
               return self::$TypeMap[$type];
           }
        }
        if(is_numeric($imageFileOrCode) && $imageFileOrCode>0 && $imageFileOrCode<count(self::$TypeMap))
        {
            return self::$TypeMap[$imageFileOrCode];
        }
        return '';
    }

    /**
     * @param $imageFile
     * @param string $key [size,attr,width,height,ctime,atime,mtime,type,dir,basename,ext,owner,filename]
     * @return bool|int|array
     */
    public static function getImageInfo($imageFile='',$key='info')
    {
        $flag = false;
        if(empty($imageFile))
        {
            if(self::getCache('filename'))
            {
                $imageFile = self::$cache['filename'];
                $flag  = true;
            }
        }
        if(empty($key))
        {
            $key = 'info';
        }
        $ret = self::getCache($key);
        if($flag && $ret )
        {
            return $ret;
        }
        try
        {
            ImageException::file_exists($imageFile);
            $types = static::supportTypes();
            ImageException::setImageFileSupport($types);
            ImageException::isImageFile($imageFile)  ;
            ImageException::type_support($imageFile) ;
        }catch (ImageException $e)
        {
            echo $e->getMessage()."\n" ;
            return false;
        }
        list($width,$height,$type,$attr) = \getimagesize($imageFile);
        if( 'info'===$key && !empty($type))
        {
            if($flag)
            {
                self::$cache['width'] = $width;
                self::$cache['height'] = $height;
                self::$cache['type'] = array(self::getImageTypeStr($type)=>$type);
                self::$cache['attr'] = $attr;
            }
            return array('width'=>$width,'height'=>$height,'type'=>$type,'attr'=>$attr);
        }
        if('width' === $key)
        {
            return $width;
        }
        if( 'height' === $key)
        {
            return $height ;
        }
        if('type'=== $key)
        {
            return $type;
        }
        if('attr'=== $key)
        {
            return $attr;
        }
        if(preg_match('/size(@(bit|b|kb|m|g|t))?/i',$key))
        {
            $flag  = explode('@',$key);
            $len   = count($flag) ;
            $real_flag = $len>1 && !empty($flag[$len-1]) ? $flag[$len-1] : '';

            $size = self::getCache('size');

            if(!$size && $flag)
            {
                    $size = filesize($imageFile);
                    self::$cache['size'] = $size ;
            }
            if(empty($real_flag))
            {
                return $size ;
            }
            $size  = self::size($size,$real_flag) . $real_flag;
            return $size;
        }
        if('ctime'=== $key)
        {
            $ret = self::getCache($key);
            if($flag && $ret)
            {
                return $ret;
            }else
            {
                $ret = filectime($imageFile);
                self::$cache[$key] = $ret;
            }

            return $ret;
        }
        if('atime'=== $key)
        {
            $ret = self::getCache($key);
            if($flag && $ret)
            {
                return $ret;
            }else
            {
                $ret = fileatime($imageFile);
                self::$cache[$key] = $ret;
            }
            return $ret;
        }
        if('mtime' === $key)
        {
            $ret = self::getCache($key);
            if($flag && $ret)
            {
                return $ret;
            }else
            {
                $ret = filemtime($imageFile);
                self::$cache[$key] = $ret;
            }
           return  $ret;
        }
        if('owner' === $key)
        {
            $ret = self::getCache($key);
            if($flag && $ret)
            {
                return $ret;
            }else
            {
                $ret = fileowner($imageFile);
                self::$cache[$key] = $ret;
            }
           return  $ret;
        }
        $tmp = pathinfo($imageFile) ;
        $ret = self::getCache($key);
        if($flag && $ret)
        {
            return $ret;
        }else
        {
            self::$cache[$key] =  $tmp[$key];
        }
        return $ret;
    }

    /**
     * @param {null|String|Int} $typeStrOrCode
     * @return array|bool|int
     */
    public static function supportTypes($typeStrOrCode=null)
    {
        $flag = \imagetypes();
        if(empty($typeStrOrCode))
        {
            $result = array();
            foreach(self::$SupportTypeCode as $key=>$value )
            {
                if($flag&$value)
                {
                    $result[$key] = true ;
                }
            }
            return $result ;
        }
        if(is_numeric($typeStrOrCode))
        {
            return ($flag & $typeStrOrCode) ;
        }
        if(is_string($typeStrOrCode))
        {
            $t = self::supportTypes();
            if(empty($t)||!is_array($t))
            {
                return false;
            }
            foreach ($t as $key =>$value)
            {
                if($key == $typeStrOrCode && true==$value)
                {
                    return true;
                }
            }
        }

        return false;
    }

    public static function getImageWidth($file)
    {
        return self::_attrImage($file,'width');
    }

    public static function getImageHeight($file)
    {
        return self::_attrImage($file,'height');
    }

    private static function _attrImage($file,$attr='height')
    {
            ImageException::emptyCheck($file,__METHOD__);
            if(is_string($file))
            {
              try
              {
                  ImageException::setImageFileSupport(self::supportTypes());
                  ImageException::isImageFile($file) && ImageException::file_exists($file);
              }catch (ImageException $e)
              {
                  echo $e->getMessage()."\n";
                  return false;
              }
              if(self::getCache('resource') && self::getCache('filename') === $file)
              {
                  if(self::getCache($attr))
                  {
                      return self::getCache($attr);
                  }
                  $h = ($attr == 'height') ? \imagesy(self::getCache('resource')) : \imagesx(self::getCache('resource'));
                  self::$cache[$attr] = $h ;
                  return $h;
              }
              $file = new self($file);
            }
            return ($attr == 'height') ? \imagesy($file->Instace()) : \imagesx($file->Instace());
    }

    public  function Instace()
    {
        if(empty(self::$cache))
        {
          return  new self(null);
        }
        else if(self::getCache('resource') && self::getCache('self'))
        {
            return self::$cache['self'] ;
        }
        $error = 'class init falied';
        $code  = ImageException::_code($error);
        throw new ImageException(ImageException::createMsgByCode($code,__CLASS__),$code);
    }

    public static function size($size,$flag='kb')
    {
            if(is_numeric($size) && $size>0)
            {
                if('bit'==$flag)
                {
                    return $size*8;
                }
                if('b' == $flag || 'B' == $flag || empty($flag))
                {
                    return $size ;
                }
                if('kb' == $flag || 'KB' === $flag)
                {
                    return $size/1000 ;
                }
                if('m' === $flag || 'M' === $flag || 'mb'===$flag || 'MB' === $flag)
                {
                    return $size/pow(1000,2);
                }
                if('g' == $flag || 'gb' == $flag || 'G'==$flag || 'GB' == $flag)
                {
                    return $size/pow(1000,3);
                }
                if('t' == $flag || 'tb' == $flag || 'T'==$flag || 'TB' == $flag)
                {
                    return $size/pow(1000,4);
                }
            }
            return false;
    }

    public static function getCache($key)
    {
        if(empty($key))
        {
            return false;
        }
        if('info'==$key && isset(self::$cache['width']) && isset(self::$cache['height']) && isset(self::$cache['type']) && isset(self::$cache['attr']))
        {
            return array(
                'width'=>self::$cache['width'],
                'height'=>self::$cache['height'],
                'type'=>self::$cache['type'],
                'attr'=>self::$cache['attr'],
            );
        }
        if(isset(self::$cache[$key]))
        {
            return self::$cache[$key];
        }
        return false;
    }

}
